package com.gwm.item.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gwm.common.enums.ExceptionEnums;
import com.gwm.common.exceptions.LyException;
import com.gwm.common.utils.BeanHelper;
import com.gwm.common.vo.PageResult;
import com.gwm.item.dto.SkuDTO;
import com.gwm.item.dto.SpuDTO;
import com.gwm.item.dto.SpuDetailDTO;
import com.gwm.item.service.*;
import com.gwm.item.pojo.TbCategory;
import com.gwm.item.pojo.TbSku;
import com.gwm.item.pojo.TbSpu;
import com.gwm.item.pojo.TbSpuDetail;
import org.apache.commons.lang.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.gwm.common.constants.RocketMQConstants.TAGS.ITEM_DOWN_TAGS;
import static com.gwm.common.constants.RocketMQConstants.TAGS.ITEM_UP_TAGS;
import static com.gwm.common.constants.RocketMQConstants.TOPIC.ITEM_TOPIC_NAME;

@Service
public class GoodsService {

    @Autowired
    private TbSpuService spuService;
    @Autowired
    private TbSpuDetailService spuDetailService;
    @Autowired
    private TbSkuService skuService;
    @Autowired
    private TbBrandService brandService;
    @Autowired
    private TbCategoryService categoryService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;


    public PageResult<SpuDTO> findSpuPage(Integer page, Integer rows, String key, Boolean saleable) {

        QueryWrapper<TbSpu> queryWrapper = new QueryWrapper<>();
        if(StringUtils.isNotEmpty(key)){
            queryWrapper.lambda().like(TbSpu::getName,key);
        }if(saleable!=null){
            queryWrapper.lambda().eq(TbSpu::getSaleable,saleable);
        }
//        设置分页
        Page<TbSpu> page1 = new Page<>(page,rows);
//        排序
        queryWrapper.orderByDesc("update_time");

        IPage<TbSpu> tbSpuIPage = spuService.page(page1, queryWrapper);

        List<TbSpu> tbSpuList = tbSpuIPage.getRecords();

        List<SpuDTO> spuDTOList = BeanHelper.copyWithCollection(tbSpuList, SpuDTO.class);

//        给spuDTO赋值
        handlerCategoryAndBrandName(spuDTOList);

//        Long total, Long totalPage, List<T> items
        return new  PageResult<>(tbSpuIPage.getTotal(),tbSpuIPage.getPages(),spuDTOList);

    }

    private void handlerCategoryAndBrandName(List<SpuDTO> spuDTOList) {
        for (SpuDTO spuDTO : spuDTOList) {
            String brandName = brandService.getById(spuDTO.getBrandId()).getName();
            spuDTO.setBrandName(brandName);
            Collection<TbCategory> tbCategories = categoryService.listByIds(spuDTO.getCategoryIds());
            String categoryName = tbCategories.stream().map(TbCategory::getName).collect(Collectors.joining("/"));
            spuDTO.setCategoryName(categoryName);  //"手机/手机通讯/手机"
        }


    }

    @Transactional
    public void saveGoods(SpuDTO spuDTO) {
//        1、spu  SPUDetail  sku
        TbSpu tbSpu = BeanHelper.copyProperties(spuDTO, TbSpu.class);
        spuService.save(tbSpu);

        TbSpuDetail tbSpuDetail = BeanHelper.copyProperties(spuDTO.getSpuDetail(), TbSpuDetail.class);
        tbSpuDetail.setSpuId(tbSpu.getId());
        spuDetailService.save(tbSpuDetail);

        List<TbSku> tbSkuList = BeanHelper.copyWithCollection(spuDTO.getSkus(), TbSku.class);

        tbSkuList.forEach(sku->{
            sku.setSpuId(tbSpu.getId());
        });

        skuService.saveBatch(tbSkuList);

//        新增索引数据
//        新增静态页面

        rocketMQTemplate.convertAndSend(ITEM_TOPIC_NAME+":"+ITEM_UP_TAGS,tbSpu.getId());
    }



    @Transactional
    public void updateGoodsSaleable(Long spuId, Boolean saleable) {
//        1、修改spu的上下架  2、修改sku的是否有效
        TbSpu tbSpu = new TbSpu();
        tbSpu.setId(spuId);
        tbSpu.setSaleable(saleable);
        spuService.updateById(tbSpu);

        UpdateWrapper<TbSku> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(TbSku::getEnable,saleable);
        updateWrapper.lambda().eq(TbSku::getSpuId,spuId);
        skuService.update(updateWrapper);

        String tag = saleable?ITEM_UP_TAGS:ITEM_DOWN_TAGS;
        rocketMQTemplate.convertAndSend(ITEM_TOPIC_NAME+":"+tag,spuId);
    }

    public SpuDetailDTO findSpuDetailBySpuId(Long spuId) {
        TbSpuDetail tbSpuDetail = spuDetailService.getById(spuId);
        return BeanHelper.copyProperties(tbSpuDetail,SpuDetailDTO.class);
    }

    public List<SkuDTO> findSkuListBySpuId(Long spuId) {

        QueryWrapper<TbSku> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TbSku::getSpuId,spuId);
        List<TbSku> tbSkuList = skuService.list(queryWrapper);

        if(CollectionUtils.isEmpty(tbSkuList)){
            throw new LyException(ExceptionEnums.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(tbSkuList,SkuDTO.class);
    }

    @Transactional
    public void updateGoods(SpuDTO spuDTO) {
        // 1 修改spu
        TbSpu tbSpu = BeanHelper.copyProperties(spuDTO, TbSpu.class);
        spuService.updateById(tbSpu);

//       2 修改SPUDetail
        TbSpuDetail tbSpuDetail = BeanHelper.copyProperties(spuDTO.getSpuDetail(), TbSpuDetail.class);
        spuDetailService.updateById(tbSpuDetail);

//        3 删除之前的sku
        QueryWrapper<TbSku> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TbSku::getSpuId,tbSpu.getId());
        skuService.remove(queryWrapper);



//        4、新增sku
        List<TbSku> tbSkuList = BeanHelper.copyWithCollection(spuDTO.getSkus(), TbSku.class);

        tbSkuList.forEach(sku->{
            sku.setSpuId(tbSpu.getId());
        });

        skuService.saveBatch(tbSkuList);

    }

    public SpuDTO findSpuBySpuId(Long spuId) {
        TbSpu tbSpu = spuService.getById(spuId);
        return BeanHelper.copyProperties(tbSpu,SpuDTO.class);
    }


    public List<SkuDTO> querySkuListByIds(List<Long> ids) {
        Collection<TbSku> tbSkuList = skuService.listByIds(ids);
        if(CollectionUtils.isEmpty(tbSkuList)){
            throw  new LyException(ExceptionEnums.GOODS_NOT_FOUND);
        }
        List<SkuDTO> skuDTOList = tbSkuList.stream().map(tbSku -> {
            return BeanHelper.copyProperties(tbSku, SkuDTO.class);
        }).collect(Collectors.toList());
        return skuDTOList;
    }

    public List<SkuDTO> findSkuListBySkuIds(List<Long> ids) {
        Collection<TbSku> tbSkuList = skuService.listByIds(ids);

        List<SkuDTO> skuDTOList = tbSkuList.stream().map(sku -> {
            return BeanHelper.copyProperties(sku, SkuDTO.class);
        }).collect(Collectors.toList());

        return skuDTOList;
    }

    public void stockMinus(Map<Long, Integer> skuIdAndNumMap) {
//        update tb_sku set stock=stock-? where id=skuId
        for (Long skuId : skuIdAndNumMap.keySet()) {
            skuService.stockMinus(skuIdAndNumMap.get(skuId),skuId);
        }



    }

    public void stockPlus(Map<Long, Integer> skuIdAndNumMap) {
        for (Long skuId : skuIdAndNumMap.keySet()) {
            skuService.stockPlus(skuIdAndNumMap.get(skuId),skuId);
        }
    }

    /**
     * 根据brandId查询商品列表
     *
     * @param brandId
     * @param cid3
     * @return
     */
    public List<SpuDTO> findSpuByBrandId(Long brandId, Long cid3) {
        QueryWrapper<TbSpu> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TbSpu::getBrandId, brandId).eq(TbSpu::getCid3, cid3);
        List<TbSpu> tbSpuList = spuService.list(queryWrapper);
        return BeanHelper.copyWithCollection(tbSpuList, SpuDTO.class);
    }


}
